package com.safe.text;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.parse.Parse;
import com.parse.ParseObject;
import android.app.Service;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class MainService extends Service {
	Boolean hasStarted = false;
	static SmsManager sms = SmsManager.getDefault();

	static Location initialLocation = null;
	static Location currentLocation = null;
	static boolean started = false;
	public static long initialTime = 0;
	static double initialLat = 0.0;
	static double initialLon = 0.0;
	public static long currentTime = 0;
	static double currentLat = 0.0;
	static double currentLon = 0.0;
	static double mph = 0.0;
	static double kph = 0.0;
	static double averagemph = 0.0;
	static double averagekph = 0.0;
	static int averageCount = 0;
	public MyLocationListener myLocationListener = new MyLocationListener();
	public static LocationManager myLocationManager;
	public static Date smsTime = new Date();
	ContentObserver contentObserver = new SMSListen(new Handler());
	static Boolean smsSent = false;
	static Boolean isDriving = false;
	static String phoneNumber = "";
	static String emailAddress = "";
	static String password = "";
	static int newLocationCount = 0;
	static String deviceNumber = "";
	static boolean isAsyncRunning = false;
	StoredData db = new StoredData(this);

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		// code to execute when the service is first created
		Parse.initialize(this, "tbLiAmAO28YdbVjTaNGJOCHyJgKvRanwIM2pzhQH",
				"jummwB87UtOWbPhhAjiAFoYgHLDB2P92JyuzYrEe");
		startListeners();
		final SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(this);
		emailAddress = prefs.getString("emailAddress", "");
		password = prefs.getString("password", "");
		BaseActivity.emailAddress = emailAddress;
		prefs.edit().putBoolean("serviceStatus", true);
		prefs.edit().commit();
	}

	@Override
	public void onDestroy() {
		// code to execute when the service is shutting down
		final SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(this);
		prefs.edit().putBoolean("serviceStatus", false);
		prefs.edit().commit();
		Log.e("status", "false");
		stopListeners();
		sendSMS(prefs.getString("phoneNumber", ""),
				"SafeText has been disabled!");
	}

	@Override
	public void onStart(Intent intent, int startid) {
		// code to execute when the service is starting up
		startListeners();
		final SharedPreferences.Editor prefsEditor = PreferenceManager
				.getDefaultSharedPreferences(this).edit();
		prefsEditor.putBoolean("serviceStatus", true);
		prefsEditor.commit();

	}

	public static String getDate(long milliSeconds, String dateFormat) {
		// Create a DateFormatter object for displaying date in specified
		// format.
		DateFormat formatter = new SimpleDateFormat(dateFormat);

		// Create a calendar object that will convert the date and time value in
		// milliseconds to date.
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(milliSeconds);
		return formatter.format(calendar.getTime());
	}

	private void startListeners() {
		if (hasStarted == false) {
			// code to register the content observer that gets SMS events
			ContentResolver contentResolver = getContentResolver();
			contentResolver.registerContentObserver(Uri.parse("content://sms"),
					true, contentObserver);
			// registers the listener that checks for gps locations
			// startGPSListener();

			hasStarted = true;
		}
	}

	private void stopListeners() {

		// code to unregister the content observer that gets SMS events
		ContentResolver contentResolver = getContentResolver();
		contentResolver.unregisterContentObserver(contentObserver);
		// unregisters the listener
		try {
			stopGPSListener();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		hasStarted = false;
	}

	public void stopGPSListener() {
		myLocationManager.removeUpdates(myLocationListener);
		Log.e("stopGPSListener", "stopped");
	}

	public void startGPSListener() {
		myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		if (myLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			myLocationManager.requestLocationUpdates(
					LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
		} else {
			myLocationManager.requestLocationUpdates(
					LocationManager.NETWORK_PROVIDER, 0, 0, myLocationListener);
		}
		Log.e("startGPSListener", "started");

	}

	public static void resetValues() {
		initialLocation = null;
		currentLocation = null;
		initialLat = 0.0;
		initialLon = 0.0;
		initialTime = 0;
		currentLat = 0.0;
		currentLon = 0.0;
		currentTime = 0;
	}

	public void getDeviceNumber(){
	    TelephonyManager mTelephonyMgr;
	    mTelephonyMgr = (TelephonyManager)
	        getSystemService(Context.TELEPHONY_SERVICE); 
	    deviceNumber = mTelephonyMgr.getLine1Number();
	    
	}
	
	public void sendSMS(String phone, String message) {
		sms.sendTextMessage(phone, null, message, null, null);
		ContentValues values = new ContentValues();
		values.put("address", phone);
		values.put("body", message);
		getContentResolver().insert(Uri.parse("content://sms/sent"), values);
		// Log.e("WORKING", "TESTISWORKING");
	}

	public void sendEmail(String email, String subject, String body) {
		Uri uri = Uri.parse("mailto:" + "trentdues@gmail.com");
		Intent myActivity2 = new Intent(Intent.ACTION_SENDTO, uri);
		myActivity2.putExtra(Intent.EXTRA_SUBJECT, subject);
		myActivity2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

		try {
			startActivity(myActivity2);
		} catch (android.content.ActivityNotFoundException ex) {
			Toast.makeText(MainService.this,
					"There are no email clients installed.", Toast.LENGTH_SHORT)
					.show();
		}
	}

	public static void getLocations() {
	//	Log.e("getLocations", "start");
		Location location = myLocationManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		// Log.e("getUpdatedLocation", myLocationListener + "" +
		// LocationManager.GPS_PROVIDER);
		if (location == null) {
			Location networkLocation = myLocationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
			if (networkLocation == null) {
				Location l = myLocationManager
						.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
				if (l != null) {
					location = l;
				}
			} else {
				location = networkLocation;
			}
		}
		if (location != null) {
			initialLocation = location;
			currentLocation = location;
			if (currentLocation != null) {
				// Log.e("cloc", "test");

				initialLocation = currentLocation;
				currentLocation = location;
			}
			// Executes if the first get locations call is null
			if (initialLat == 0.0 || initialLon == 0.0) {
				initialLat = location.getLatitude();
				initialLon = location.getLongitude();
				initialTime = System.currentTimeMillis();
			}

			else {

				if (currentLat != 0.0 || currentLon != 0.0) {
					initialLat = currentLat;
					initialLon = currentLon;
					initialTime = currentTime;
				}
				currentLat = location.getLatitude();
				currentLon = location.getLongitude();
				currentTime = System.currentTimeMillis();
				// currentLocation.setLatitude(currentLat + 0.1);
				// currentLocation.setLongitude(currentLon + 0.1);
				Location l1 = new Location(" ");
				Location l2 = new Location(" ");
				l1.setLatitude(initialLat);
				l1.setLongitude(initialLon);
				l2.setLatitude(currentLat);
				l2.setLongitude(currentLon);
				// Log.e("lat1", initialLat + "");
				// Log.e("lon1", initialLon + "");
				// Log.e("lat2", currentLat + "");
				// Log.e("lon2", currentLon + "");
				double distance_meters = (double) l1.distanceTo(l2);
				// Log.e("listOFloat",
				// initialLocation.distanceTo(currentLocation)+ "");
				double distance_miles = distance_meters / 1609.344;
				double time_milisec = ((double) (currentTime - initialTime));
				double time_hours = time_milisec / 3600000;

				// distance_meters = 100;
				// distance_miles = 0.0621371;

				// Log.e("distance", "" + distance_meters);
				kph = distance_meters / (time_milisec / 1000);
				mph = distance_miles / time_hours;
				// mps to kph
				kph = kph * 3.6;
				DecimalFormat df = new DecimalFormat("#.##");
				mph = Double.parseDouble(df.format(mph));
				kph = Double.parseDouble(df.format(kph));
				BaseActivity.kph = kph;
				BaseActivity.mph = mph;
				averageCount++;
				averagemph = mph + averagemph;
				averagekph = kph + averagekph;
				// averagemph = averagemph + 5.17;
				// tmph.setText(String.valueOf(mph) + "mph");
				// tmps.setText(String.valueOf(meters_per_second) + "m/s");
			}

		} else {
			Log.e("getlocations", "locations are null");
		}
		// myLocationManager.removeUpdates(myLocationListener);
	//	Log.e("getlocations", "end");
	}

	public void getSpeed() {
		getLocations();
		// MainService.isDriving = isDriving();
		Handler handler = new Handler();
		handler.postDelayed(new Runnable() {
			public void run() {
				getLocations();
			}
		}, 2000);

	}

	public void SendAndSave(){
		  final SharedPreferences prefs = PreferenceManager
					.getDefaultSharedPreferences(MainService.this);
		  if (isDriving){
		if (phoneNumber != null) {
			if (prefs.getBoolean(
					BaseActivity.KEY_SMS_PREF,
					true)) {
				sendSMS(phoneNumber,
						"SafeText Notification: " + deviceNumber + " sent a text while moving approximately " + averagemph + " mph");
			}

			db.open();
			db.insertSms(
					getDate(System
							.currentTimeMillis(),
							"MM/dd/yyyy"),
							getDate(System
							.currentTimeMillis(),
							"h:mm aa"),
					String.valueOf(averagemph),
					String.valueOf(averagekph));
			// change averagemph to mps
			db.close();
			ParseObject dhObject = new ParseObject(
					"DrivingHistory");
			dhObject.put(
					"SMSSentDate",
					getDate(System
							.currentTimeMillis(),
							"MM/dd/yyyy"));
			dhObject.put(
					"SMSSentTime",
					getDate(System
							.currentTimeMillis(),
							"h:mm aa"));
			dhObject.put("UserId",
					BaseActivity.UserId);
			dhObject.put("mph",
					String.valueOf(mph));
			dhObject.put("kph",
					String.valueOf(kph));
			dhObject.put("averagemph",
					String.valueOf(averagemph));
			dhObject.put("averagekph",
					String.valueOf(averagekph));
			dhObject.put("latitude",
					String.valueOf(currentLat));
			dhObject.put("longitude",
					String.valueOf(currentLon));
			dhObject.put("sentFromNumber",
					deviceNumber);
			dhObject.saveInBackground();
			resetValues();
			averagekph = 0;
			averagemph = 0;
			averageCount = 0;

		}
	}
		//	Log.e("endoftemp", "end");
			stopGPSListener();
	}
	
	class SMSListen extends ContentObserver {

		public SMSListen(Handler handler) {
			super(handler);
			Log.e("SMSListen", "start");
		}

		@Override
		public boolean deliverSelfNotifications() {
			return false;
		}

		@Override
		public void onChange(boolean selfChange) {
			super.onChange(selfChange);
			// Log.e("sms", "smsEvent");

			Uri uriSMSURI = Uri.parse("content://sms/");
			Cursor cur = getContentResolver().query(uriSMSURI, null, null,
					null, null);
			cur.moveToNext();
			String protocol = cur.getString(cur.getColumnIndex("protocol"));
			String type = cur.getString(cur.getColumnIndex("type"));
		//	Log.e("type", type);
			// Log.e("SMS", "SMS PROTOCOL = " + protocol);
			if (protocol == null) {
				// put code here because sms sent is true
				// The calculation is only done for 1 text in 20 seconds
				if ((smsTime.getTime() + 30000) <= System.currentTimeMillis()) {
					startGPSListener();
					// getUpdates();
					smsTime = new Date();
					smsSent = true;
					getDeviceNumber();
					  final SharedPreferences prefs = PreferenceManager
								.getDefaultSharedPreferences(MainService.this);
						emailAddress = prefs.getString(
								"emailAddress", "");
						password = prefs.getString("password",
								"");
						phoneNumber = prefs.getString("phoneNumber",
								"");
					isAsyncRunning = true;
					Async task = new Async();
					task.execute("");
					while(isAsyncRunning){
						
					}
					SendAndSave();
					
				}


			} else {
				Log.e("SMS App", "Receive");
			}

		}
	}

	public class MyLocationListener implements
			android.location.LocationListener {

		public void onLocationChanged(Location location) {
			// Log.e("onLocationChanged", location.getAccuracy() + "");
			if (newLocationCount <= 5) {
				newLocationCount++;

				// Log.e("newLocationCount", newLocationCount + "");
			} else {
				newLocationCount = 0;
			}

		}

		public void onProviderDisabled(String provider) {
			Log.e("onProviderDisabled", "locationListener onProviderDisabled: "
					+ provider);
			myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
			if (myLocationManager
					.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
				myLocationManager.requestLocationUpdates(
						LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
			} else {
				myLocationManager.requestLocationUpdates(
						LocationManager.NETWORK_PROVIDER, 0, 0,
						myLocationListener);
			}
			// prefsEditor.putString("gpsStatus", provider + " disabled"
			// .toString());
			// prefsEditor.commit();
		}

		public void onProviderEnabled(String provider) {
			Log.e("onProviderEnabled", "locationListener onProviderEnabled: "
					+ provider);
			myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
			if (myLocationManager
					.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
				myLocationManager.requestLocationUpdates(
						LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
			} else {
				myLocationManager.requestLocationUpdates(
						LocationManager.NETWORK_PROVIDER, 0, 0,
						myLocationListener);
			}
			// prefsEditor.putString("gpsStatus", provider + " enabled"
			// .toString());
			// prefsEditor.commit();
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
			Log.e("onStatusChanged", "locationListener onStatusChanged: "
					+ provider + "status: " + status);
			// prefsEditor.putString("gpsStatus", provider + " status is " +
			// String.valueOf(status)
			// .toString());
			// prefsEditor.commit();
		}

	}

}
// The definition of our task class
   class Async extends AsyncTask<String, Integer, String> {

  
  protected void onPreExecute() {
     super.onPreExecute();
    // displayProgressBar("Downloading...");
  }

  protected String doInBackground(String... params) {
	  try {	
		  Thread.sleep(5000);
	  MainService.getLocations();
//	  Log.e("speed", MainService.mph + " | " + MainService.averagemph  + " | " + MainService.averageCount);
		Thread.sleep(3000);
		  MainService.getLocations();
	//	  Log.e("speed2", MainService.mph + " | " + MainService.averagemph  + " | " + MainService.averageCount);

		if (BaseActivity.UserId == "") {
			BaseActivity.getUserObjectId(
					MainService.emailAddress, MainService.password);
		}
		MainService.resetValues();
	      Thread.sleep(3000);
		  MainService.getLocations();
		//  Log.e("speed3", MainService.mph + " | " + MainService.averagemph  + " | " + MainService.averageCount);
			Thread.sleep(3000);
			  MainService.getLocations();
		//	  Log.e("speed4", MainService.mph + " | " + MainService.averagemph  + " | " + MainService.averageCount);
			  Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


			try {
				MainService.averagemph = MainService.averagemph / MainService.averageCount;
				MainService.averagekph = MainService.averagekph / MainService.averageCount;
				DecimalFormat df = new DecimalFormat(
						"#.##");
				MainService.averagemph = Double.parseDouble(df
						.format(MainService.averagemph));
				MainService.averagekph = Double.parseDouble(df
						.format(MainService.averagekph));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			  Log.e("speedfinal", MainService.mph + " | " + MainService.averagemph  + " | " + MainService.averageCount);
		//	Log.e("avemph", MainService.averagemph + "");
			//Log.e("avekph", MainService.averagekph + "");
			if (MainService.averagemph >= 12) {
				Log.v("STATUS", "You are Driving!");
				// Log.e("Email Address", "" +
				// BaseActivity.emailAddress);
			
				// if (BaseActivity.emailAddress != null
				// ||
				// BaseActivity.emailAddress != ""){
				// Log.e("Email Address", "" + "test");
				// sendEmail(BaseActivity.emailAddress,
				// "SafeText Alert", "Test");
				// }
				MainService.isDriving = true;
			} else {
				MainService.isDriving = false;
				Log.v("STATUS", "You are not Driving!");
			}
			MainService.isAsyncRunning = false;
			return "isDriving";
			
		//	MainService.stopGPSListener();
		  
  }

  @Override
  protected void onProgressUpdate(Integer... values) {
     super.onProgressUpdate(values);
    // updateProgressBar(values[0]);
  }

  @Override
  protected void onPostExecute(String result) {
     super.onPostExecute(result);
  //   dismissProgressBar();
  }

  }
  
  
